<template>
  <svg 
    xmlns="http://www.w3.org/2000/svg"
    version="1.1"
    class="leader-line"
    :width="`${width}px`" 
    :height="`${height}px`"
    :style="style"
    :viewBox="viewBox">
    <path
      :d="d" 
      :stroke="color"
      stroke-width="3"
      fill="transparent"
      :transform="lineTransform"/>
    <polygon 
      points="-8,-8 8,0 -8,8 -5,0"
      :stroke="color"
      :fill="color"
      :transform="arrowTransform"/>
  </svg>
</template>

<script>
import path from '../utils/path'

const margin = 8

export default {
  name: 'LeaderLine',
  props: {
    start: {
      type: Object,
      validator: pointValidator
    },
    end: {
      type: Object,
      validator: pointValidator
    },
    color: {
      type: String,
      default: '#aaa'
    }
  },
  computed: {
    minX () {
      return Math.min(this.start.x, this.end.x)
    },
    minY () {
      return Math.min(this.start.y, this.end.y)
    },
    // 坐标差
    diffX () {
      return Math.abs(this.start.x - this.end.x)
    },
    diffY () {
      return Math.abs(this.start.y - this.end.y)
    },
    width () {
      return this.diffX + margin * 2
    },
    height () {
      return this.diffY + margin * 2
    },
    d () {
      return path(this.start, this.end, this.curv)
    },
    arrowTransform () {
      let translate = `translate(${this.end.x + margin},${this.end.y + margin})`
      if (this.direction === 'right') {
        translate += ' rotate(180)'
      }
      return translate
    },
    lineTransform () {
      return `translate(${margin},${margin})`
    },
    // 箭头方向
    direction () {
      return this.start.x - this.end.x < 0 ? 'left' : 'right'
    },
    viewBox () {
      // 最小X轴数值；最小y轴数值；宽度；高度
      return `${this.minX} ${this.minY} ${this.width} ${this.height}`
    },
    style () {
      return {
        left: (Math.min(this.start.x, this.end.x) - margin) + 'px',
        top: (Math.min(this.start.y, this.end.y) - margin) + 'px',
      }
    }
  }
}

function pointValidator (point) {
  return isNumber(point.x) && isNumber(point.y)
}
function isNumber(obj) {
  return obj === +obj
}
</script>

<style lang="scss" scoped>
.leader-line {
  position: absolute;
}
</style>
